Octubre 30 de 2020
Las redes neuronales artificiales son una representación abstracta del comportamiento de una red neuronal biológica. Su contexto se remonta a 1943, año en el cual McCulloch y Pitts proponen el primer modelo neuronal, dicho modelo era un modelo binario, en el cual cada neurona tenía un escalón o umbral prefijado. De esta manera sirvió de base para los modelos posteriores.
Red neuronal
Las redes neuronales están compuestas por capas de neuronas que se comunican entre si y es posible dividirlas de la siguiente manera:
Estructura
Función lineal de tipo hiperplano: Es una función de base cuyo valor de red corresponde a una combinación lineal de las entradas.
\[u_{i}(w,x)=\sum_{j=1}^{n}w_{ij}x_{j}\]
Función radial de tipo hiperesférico:
\[u_{i}(w,x)= \sqrt{\sum_{j=1}^{n}(x_{j}-w_{ij})^{2}}\]Las funciones de activación se dividen en dos tipos como: lineal y no lineal
Red neuronal
Asignamos a cada conexión neuronal un peso con un valor pequeño, pero no nulo.
Introducimos la primera observación de nuestro conjunto de entrenamiento por la capa inicial de la red neuronal.
La información se propaga de izquierda a derecha, activando cada neurona que ahora es afectada por el peso de cada conexión, hasta llegar a la capa de neuronas de salida, obteniendo el resultado final para esa observación en concreto.
Medimos el error que hemos cometido para esa observación.
Comienza la propagación hacia atrás de derecha a izquierda, actualizando los pesos de cada conexión neuronal, dependiendo de la responsabilidad del peso actualizado en el error cometido.
Repetimos los pasos desde el paso 2, actualizando todos los pesos para cada observación o conjunto de observaciones de nuestro conjunto de entrenamiento.
Cuando todas las observaciones del conjunto de entrenamiento ha pasado por la red neuronal, hemos completado lo que se denomina un Epoch. Podemos realizar tantos Epochs como creamos convenientes.
La mayoría de las aplicaciones de las redes neuronales consisten en:
Finanzas: Previsión de la evolución de los precios, Valoración del riesgo de los créditos, Identificación de falsificaciones, Interpretación de firmas.
Manufacturación: Robots automatizados y sistemas de control (visión artificial y sensores de presión, temperatura, gas, etc.), Inspección de la calidad.
Militares: Clasificación de las señales de radar y Reconocimiento y seguimiento en el tiro al blanco.
Se hará uso del conjunto de datos denominado: “Boston” perteneciente al paquete MASS. El conjunto de datos de Boston es una colección de datos sobre el valor de las viviendas en los suburbios de Boston. Nuestro objetivo es predecir el valor medio de las viviendas ocupadas por sus propietarios (medv) utilizando todas las demás variables continuas disponibles.
set.seed(500) suppressMessages(library(MASS)) suppressMessages(library(neuralnet)) data <- Boston
Inicialmente se verifica que no falte ningún punto de datos; de lo contrario, es necesario corregir el conjunto.
apply(data,2,function(x) sum(is.na(x)))
## crim zn indus chas nox rm age dis rad tax ## 0 0 0 0 0 0 0 0 0 0 ## ptratio black lstat medv ## 0 0 0 0
index <- sample(1:nrow(data),round(0.75*nrow(data))) train <- data[index,] test <- data[-index,] lm.fit <- glm(medv~., data=train) pr.lm <- predict(lm.fit,test) MSE.lm <- sum((pr.lm - test$medv)^2)/nrow(test)
summary(lm.fit)
## ## Call: ## glm(formula = medv ~ ., data = train) ## ## Deviance Residuals: ## Min 1Q Median 3Q Max ## -15.2113 -2.5587 -0.6552 1.8275 29.7110 ## ## Coefficients: ## Estimate Std. Error t value Pr(>|t|) ## (Intercept) 31.111702 5.459811 5.698 2.49e-08 *** ## crim -0.111372 0.033256 -3.349 0.000895 *** ## zn 0.042633 0.014307 2.980 0.003077 ** ## indus 0.001483 0.067455 0.022 0.982473 ## chas 1.756844 0.981087 1.791 0.074166 . ## nox -18.184847 4.471572 -4.067 5.84e-05 *** ## rm 4.760341 0.480472 9.908 < 2e-16 *** ## age -0.013439 0.014101 -0.953 0.341190 ## dis -1.553748 0.218929 -7.097 6.65e-12 *** ## rad 0.288181 0.072017 4.002 7.62e-05 *** ## tax -0.013739 0.004060 -3.384 0.000791 *** ## ptratio -0.947549 0.140120 -6.762 5.38e-11 *** ## black 0.009502 0.002901 3.276 0.001154 ** ## lstat -0.388902 0.059733 -6.511 2.47e-10 *** ## --- ## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1 ## ## (Dispersion parameter for gaussian family taken to be 20.23806) ## ## Null deviance: 32463.5 on 379 degrees of freedom ## Residual deviance: 7407.1 on 366 degrees of freedom ## AIC: 2237 ## ## Number of Fisher Scoring iterations: 2
Antes de instalar una red neuronal, es necesario realizar algunos preparativos. Como primer paso, se aborda el preprocesamiento de datos. Aquí se normalizan los datos antes de entrenar la red neuronal.
Se elige el método min-max y se escalan los datos en el intervalo [0,1]. Normalmente, el escalado en los intervalos [0,1] o [-1,1] tiende a dar mejores resultados. Por lo tanto, escalamos y dividimos los datos antes de continuar:
maxs <- apply(data, 2, max) mins <- apply(data, 2, min) scaled <- as.data.frame(scale(data, center = mins, scale = maxs - mins)) train_ <- scaled[index,] test_ <- scaled[-index,]
En esta ocasión, vamos a utilizar 2 capas ocultas con esta configuración:
\[13: 5: 3: 1\]
La capa de entrada tiene 13 entradas, las dos capas ocultas tienen 5 y 3 neuronas y la capa de salida tiene, por supuesto, una única salida ya que estamos haciendo regresión.
n <- names(train_)
f <- as.formula(paste("medv ~", paste(n[!n %in% "medv"], collapse = " + ")))
nn <- neuralnet(f,data=train_,hidden=c(5,3),linear.output=T)
plot(nn)
El paquete neuralnet proporciona una buena herramienta para trazar el modelo. Esta es la representación gráfica del modelo con los pesos en cada conexión:
Modelo red neuronal
Las líneas negras muestran las conexiones entre cada capa y los pesos en cada conexión.
Las líneas azules muestran el término de sesgo agregado en cada paso.
El sesgo se puede pensar como la intersección de un modelo lineal.
Finalmente, el algoritmo de entrenamiento ha convergido y, por lo tanto, el modelo está listo para ser utilizado.
Ahora es posible predecir los valores para el conjunto de prueba y calcular el MSE.
pr.nn <- compute(nn,test_[,1:13]) pr.nn_ <- pr.nn$net.result*(max(data$medv)-min(data$medv))+min(data$medv) test.r <- (test_$medv)*(max(data$medv)-min(data$medv))+min(data$medv) MSE.nn <- sum((test.r - pr.nn_)^2)/nrow(test_)
Se comparan los dos MSE para el modelo estimado de forma tradicional y por mediante la red neuronal:
print(paste(MSE.lm,MSE.nn))
## [1] "31.2630222372615 16.4595537665717"
Los resultados muestran que la red neuronal está realizando una mejor predicción para los “medv” que el modelo lineal.
A continuación se muestra un primer enfoque visual del rendimiento de la red y el modelo lineal en el conjunto de prueba.
A partir de la figura anterior es posible evidenciar que las predicciones hechas por la red neuronal están (en general) más concentradas alrededor de la línea (una alineación perfecta con la línea indicaría un MSE de 0 y, por lo tanto, una predicción perfecta ideal) que las realizadas por el modelo lineal.
A continuación se muestra una comparación visual más útil:
Red neuronal real vs. predicción